package main

import (
	"bufio"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"net"
)

const (
	maxDataSize = 1024 * 1024 // 最大允许数据长度 1MB
	headerSize  = 4           // 长度前缀头大小 (uint32)
)

func process(conn net.Conn) {
	defer conn.Close()
	fmt.Printf("客户端连接: %s\n", conn.LocalAddr())

	// 使用带缓冲的Reader提高效率
	reader := bufio.NewReader(conn)

	for {
		// 1. 读取消息头 (4字节长度前缀)
		header := make([]byte, headerSize)
		if _, err := io.ReadFull(reader, header); err != nil {
			if errors.Is(err, io.EOF) {
				fmt.Println("客户端关闭连接")
			} else {
				fmt.Printf("读取头错误: %v\n", err)
			}
			break
		}

		// 2. 解析数据长度 (大端序)
		dataSize := binary.BigEndian.Uint32(header)

		// 3. 校验数据长度
		if dataSize > maxDataSize {
			fmt.Printf("数据长度超过限制: %d > %d\n", dataSize, maxDataSize)
			break
		}

		// 4. 读取实际数据
		data := make([]byte, dataSize)
		if _, err := io.ReadFull(reader, data); err != nil {
			fmt.Printf("读取数据错误: %v\n", err)
			break
		}

		// 处理业务逻辑
		fmt.Printf("接收 %d 字节: %q\n", dataSize, string(data[:min(20, len(data))]))

		// 5. 构造响应 (同样使用长度前缀)
		response := []byte("服务端响应: " + string(data))
		responseHeader := make([]byte, headerSize)
		binary.BigEndian.PutUint32(responseHeader, uint32(len(response)))

		// 6. 发送响应
		if _, err := conn.Write(append(responseHeader, response...)); err != nil {
			fmt.Printf("发送响应错误: %v\n", err)
			break
		}
	}
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func main() {
	lis, err := net.Listen("tcp", "127.0.0.1:20000")
	if err != nil {
		panic(fmt.Sprintf("启动失败: %v", err))
	}
	defer lis.Close()

	fmt.Println("服务端已启动 (支持粘包处理)")

	for {
		conn, err := lis.Accept()
		if err != nil {
			fmt.Printf("接受连接失败: %v\n", err)
			continue
		}

		go process(conn)
	}
}
